home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
UUPC11QS.ARJ
/
CONFIGUR.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-07
|
19KB
|
497 lines
/*--------------------------------------------------------------------*/
/* c o n f i g u r . c */
/* */
/* Support routines for UUPC/extended */
/* */
/* Changes Copyright 1990, 1991 (c) Andrew H. Derbyshire */
/* */
/* History: */
/* 21Nov1991 Break out of lib.c ahd */
/*--------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
/*--------------------------------------------------------------------*/
/* UUPC/extended include files */
/*--------------------------------------------------------------------*/
#include "lib.h"
#include "hlib.h"
/*--------------------------------------------------------------------*/
/* Global variables */
/*--------------------------------------------------------------------*/
currentfile();
boolean bflag[F_LAST]; /* Initialized to zero by compiler */
char *aliases = NULL;
char *anonymous = NULL;
char *archivedir = NULL;
char *confdir = NULL;
char *domain = NULL;
char *E_altsignature = NULL;
char *E_backup = NULL;
char *E_charset = NULL;
char *E_editor = NULL;
char *E_filesent = NULL;
char *E_inmodem = NULL;
char *E_mailext = NULL;
char *E_pager = NULL;
char *E_rmail = NULL;
char *E_rnews = NULL;
char *E_signature = NULL;
char *E_uuxqtpath = NULL;
char *fdomain = NULL;
char *homedir = NULL;
char *localdomain = NULL;
char *mailbox = NULL;
char *maildir = NULL;
char *mailserv = NULL;
char *name = NULL;
char *newsdir = NULL;
char *newsserv = NULL;
char *nodename = NULL;
char *organization = NULL;
char *postmaster = NULL;
char *pubdir = NULL;
char *replyto = NULL;
char *spooldir = NULL;
char *tempdir = NULL;
static char *dummy = NULL;
INTEGER maxhops = 20; /* ahd */
INTEGER PacketTimeout = 10; /* Allow ten seconds per packet */
INTEGER PortTimeout = 0; /* Computed default based on Packet
timeout */
INTEGER MaxErr= 10; /* Allowed errors per single packet */
INTEGER xfer_bufsize = BUFSIZ;/* Buffering used for file transfers */
static boolean getrcnames(char **sysp,char **usrp);
/*--------------------------------------------------------------------*/
/* The following table controls the configuration files processing */
/*--------------------------------------------------------------------*/
static CONFIGTABLE table[] = {
"aliases", &aliases, B_TOKEN|B_MUA,
"altsignature", &E_altsignature, B_TOKEN|B_MUA,
"anonymouslogin",&anonymous, B_GLOBAL|B_TOKEN|B_UUIO,
"archivedir", &archivedir, B_REQUIRED|B_GLOBAL|B_TOKEN|B_NEWS,
"backupext", &E_backup, B_TOKEN|B_MUA,
"confdir", &confdir, B_REQUIRED|B_GLOBAL|B_TOKEN|B_ALL,
"charset", &E_charset, B_TOKEN|B_GLOBAL|B_SPOOL,
"domain", &domain, B_REQUIRED|B_GLOBAL|B_TOKEN|B_ALL,
"editor", &E_editor, B_STRING|B_MUA|B_NEWS,
"filesent", &E_filesent, B_TOKEN|B_MUA|B_NEWS,
"folders", &dummy, B_TOKEN|B_MUSH ,
"fromdomain", &fdomain, B_GLOBAL|B_MAIL|B_NEWS|B_TOKEN,
"home", &homedir, B_STRING|B_REQUIRED|B_ALL,
"inmodem", &E_inmodem, B_GLOBAL|B_TOKEN|B_UUIO,
"localdomain", &localdomain, B_GLOBAL|B_TOKEN|B_MAIL,
"mailbox", &mailbox, B_REQUIRED|B_TOKEN|B_ALL,
"mailext", &E_mailext, B_TOKEN|B_MAIL,
"maildir", &maildir, B_REQUIRED|B_GLOBAL|B_TOKEN|B_MAIL,
"mailserv", &mailserv, B_REQUIRED|B_GLOBAL|B_TOKEN|B_ALL,
"maximumerrors", (char **) &MaxErr, B_MTA | B_INTEGER | B_GLOBAL,
"maximumhops", (char **) &maxhops, B_MTA | B_INTEGER | B_GLOBAL,
"mushdir", &dummy, B_GLOBAL|B_TOKEN|B_MUSH,
"name", &name, B_REQUIRED|B_ALL,
"newsdir", &newsdir, B_REQUIRED|B_GLOBAL|B_TOKEN|B_NEWS,
"newsserv", &newsserv, B_GLOBAL|B_TOKEN|B_NEWS,
"nodename", &nodename, B_REQUIRED|B_GLOBAL|B_TOKEN|B_ALL,
"options", (char **) bflag, B_ALL|B_BOOLEAN,
"organization", &organization, B_STRING|B_MUA|B_NEWS,
"packettimeout", (char **) &PacketTimeout, B_UUIO | B_INTEGER | B_GLOBAL,
"pager", &E_pager, B_STRING|B_MUA|B_NEWS,
"path", &E_uuxqtpath, B_STRING|B_UUIO|B_GLOBAL,
"porttimeout", (char **) &PortTimeout, B_UUIO | B_INTEGER | B_GLOBAL,
"postmaster", &postmaster, B_REQUIRED|B_GLOBAL|B_TOKEN|B_MTA,
"pubdir", &pubdir, B_REQUIRED|B_GLOBAL|B_TOKEN|B_SPOOL,
"replyto", &replyto, B_TOKEN|B_MUA|B_NEWS,
"rmail", &E_rmail, B_REQUIRED|B_GLOBAL|B_TOKEN|B_ALL,
"rnews", &E_rnews, B_REQUIRED|B_GLOBAL|B_TOKEN|B_UUIO,
"signature", &E_signature, B_TOKEN|B_MUA|B_NEWS,
"spooldir", &spooldir, B_REQUIRED|B_GLOBAL|B_TOKEN|B_SPOOL|B_NEWS,
"tempdir", &tempdir, B_REQUIRED|B_GLOBAL|B_TOKEN|B_ALL,
"transferbuffer", (char **) &xfer_bufsize, B_UUIO | B_INTEGER | B_GLOBAL,
nil(char)
}; /* table */
/*--------------------------------------------------------------------*/
/* Boolean options shared by all programs */
/*--------------------------------------------------------------------*/
FLAGTABLE configFlags[] = {
"askcc", F_ASKCC, B_LOCAL,
"autoedit", F_AUTOEDIT, B_LOCAL,
"autoinclude", F_AUTOINCLUDE, B_LOCAL,
"autoprint", F_AUTOPRINT, B_LOCAL,
"autosign", F_AUTOSIGN, B_LOCAL,
"backup", F_BACKUP, B_LOCAL,
"doskey", F_DOSKEY, B_LOCAL,
"dot", F_DOT, B_LOCAL,
"expert", F_EXPERT, B_LOCAL,
"forwardsave", F_SAVERESENT, B_LOCAL,
"fromsep", F_FROMSEP, B_LOCAL,
"pager", F_PAGER, B_LOCAL,
"purge", F_PURGE, B_LOCAL,
"save", F_SAVE, B_LOCAL,
"verbose", F_VERBOSE, B_LOCAL,
"bang", F_BANG, B_GLOBAL,
"directory", F_DIRECT, B_GLOBAL,
"history", F_HISTORY, B_GLOBAL,
"kanji", F_KANJI, B_GLOBAL,
"monocase", F_ONECASE, B_GLOBAL,
"multiqueue", F_MULTI, B_GLOBAL,
"syslog", F_SYSLOG, B_GLOBAL,
nil(char)
} ;
/*--------------------------------------------------------------------*/
/* p r o c e s s c o n f i g */
/* */
/* Handle a single line of a configuration file */
/*--------------------------------------------------------------------*/
boolean processconfig(char *buff,
SYSMODE sysmode,
CONFIGBITS program,
CONFIGTABLE *table,
FLAGTABLE *btable)
{
CONFIGTABLE *tptr;
char *cp;
/*--------------------------------------------------------------------*/
/* break out the keyword from its value */
/*--------------------------------------------------------------------*/
if ((cp = strchr(buff, '=')) == nil(char))
{
printmsg(0,"Missing equals sign after keyword \"%s\", ignored", buff);
return TRUE;
}
*cp++ = '\0';
strlwr(buff);
/*--------------------------------------------------------------------*/
/* Scan the table for its value */
/*--------------------------------------------------------------------*/
for (tptr = table; tptr->sym != nil(char); tptr++)
{
boolean error = FALSE;
if (equal(buff, tptr->sym)) {
if ((tptr->bits & B_GLOBAL) && (sysmode != SYSTEM_CONFIG))
printmsg(0,
"User specified system parameter \"%s\" ignored.",
tptr->sym);
/*--------------------------------------------------------------------*/
/* Handle Boolean options */
/*--------------------------------------------------------------------*/
else {
if (tptr->bits & B_BOOLEAN)
options(cp, sysmode, btable, (boolean *) tptr->loc);
/*--------------------------------------------------------------------*/
/* Handle integer values */
/*--------------------------------------------------------------------*/
else if (tptr->bits & B_INTEGER)
{
int *value = (int *) tptr->loc;
cp = strtok(cp,WHITESPACE);
if ( equal(cp,"0"))
*value = 0;
else {
*value = atoi(cp);
if ( *value == 0)
{
printmsg(0,
"Unable to convert \"%s\" value \"%s\" to integer",
buff, cp);
error = TRUE;
} /* if */
} /* else */
} /* else */
/*--------------------------------------------------------------------*/
/* Handle lists of tokens */
/*--------------------------------------------------------------------*/
else if ((tptr->bits & program) && (tptr->bits & (B_LIST | B_CLIST)))
{
char **list = malloc( 50 * sizeof (*list));
char *colon;
int words;
checkref( list );
if (tptr->bits & B_CLIST) /* Use colon as delimiter? */
while ( (colon = strchr( cp , ':')) != NULL)
*colon = ' '; /* Make colons spaces ... */
words = getargs(cp, list);
if( words > 49)
panic();
if (words > 0)
{
char **savelist = (char **) *(tptr->loc);
if (savelist != NULL)
{
while( *savelist != NULL)
if (strlen(*savelist))
free( *savelist++);
free( *(tptr->loc) );
}
list = realloc( list, (words+1) * sizeof(*list));
checkref( list );
*(tptr->loc) = (char *) list;
list[words] = NULL;
while( *list != NULL)
{
if (strlen(*list))
{
*list = strdup(*list);
checkref( *list++ );
}
else
*list++ = "";
} /* while */
} /* if (words > 0) */
else {
printmsg(0,"No parameters given for keyword \"%s\"",
buff);
error = TRUE;
free( list );
} /* else */
} /* else if */
/*--------------------------------------------------------------------*/
/* Handle single tokens and strings */
/*--------------------------------------------------------------------*/
else if (tptr->bits & program)
{
if (*(tptr->loc) != nil(char))
free(*(tptr->loc)); /* free the previous one */
while( *cp == ' ' ) /* Trim leading whitespace */
cp++;
if (*cp == '\0')
{
error = TRUE;
printmsg(0,"No parameter given for keyword \"%s\""
", ignored.",
buff);
} /* if */
if (tptr->bits & B_TOKEN) /* One word value? */
cp = strtok(cp,WHITESPACE); /* Yes --> Tokenize */
*(tptr->loc) = strdup(cp); /* Save string */
checkref( *(tptr->loc) ); /* Verify malloc() */
} /* else */
} /* else */
if (!error)
tptr->bits |= B_FOUND;
return TRUE; /* Report we found the keyword */
} /* if (equal(buff, tptr->sym)) */
} /* for */
/*--------------------------------------------------------------------*/
/* We didn't find the keyword; report failure to the caller */
/*--------------------------------------------------------------------*/
return FALSE;
} /* processconfig */
/*--------------------------------------------------------------------*/
/* g e t c o n f i g */
/* */
/* Process a single configuration file */
/*--------------------------------------------------------------------*/
boolean getconfig(FILE *fp,
SYSMODE sysmode,
CONFIGBITS program,
CONFIGTABLE *table,
FLAGTABLE *btable)
{
char buff[BUFSIZ];
char *cp;
while(!(fgets(buff, sizeof buff, fp) == nil(char))) {
if ((*buff == '\n') || (*buff == '#'))
continue; /* comment line */
if (*(cp = buff + strlen(buff) - 1) == '\n')
*cp = '\0';
if (!processconfig(buff,sysmode,program,table,btable))
printmsg(0,
"Unknown keyword \"%s\" in %s configuration file ignored",
buff, sysmode ? "system" : "user");
} /*while*/
return TRUE;
} /*getconfig*/
/*--------------------------------------------------------------------*/
/* o p t i o n s */
/* */
/* Process a line of boolean option flags. */
/*--------------------------------------------------------------------*/
void options(char *s, SYSMODE sysmode , FLAGTABLE *flags, boolean *barray)
{
char *token;
strlwr(s);
token = strtok(s,WHITESPACE);
while (token != NULL)
{
size_t subscript;
boolean hit = FALSE;
boolean negate;
negate = equaln(token,"no",2) && (strlen(token) > 2);
for (subscript = 0; (subscript < F_LAST) && !hit; subscript++)
{
if ((flags[subscript].bits & B_GLOBAL) && (sysmode != SYSTEM_CONFIG))
continue;
if (negate)
{
if (equal(&token[2],flags[subscript].sym))
{
barray[ flags[subscript].position ] = FALSE;
hit = TRUE;
}
} /* if negate */
else {
if (equal(token,flags[subscript].sym))
{
barray[ flags[subscript].position ] = TRUE;
hit = TRUE;
}
} /* else */
} /* for */
if (!hit)
printf("Invalid or system option '%s' specified\n",token);
token = strtok(NULL,WHITESPACE); /* Step to next token on line */
} /* while */
} /* options */
/*--------------------------------------------------------------------*/
/* c o n f i g u r e */
/* */
/* Define the global parameters of UUPC/extended */
/*--------------------------------------------------------------------*/
boolean configure( CONFIGBITS program)
{
char *sysrc, *usrrc;
FILE *fp;
boolean success;
CONFIGTABLE *tptr;
if (!getrcnames(&sysrc, &usrrc))
return FALSE;
/*--------------------------------------------------------------------*/
/* Process the system configuration file */
/*--------------------------------------------------------------------*/
if ((fp = FOPEN(sysrc, "r", TEXT)) == nil(FILE)) {
printmsg(0, "Cannot open system configuration file \"%s\"", sysrc);
printerr(sysrc);
return FALSE;
}
success = getconfig(fp, SYSTEM_CONFIG, program, table, configFlags);
fclose(fp);
if (!success)
return FALSE;
/*--------------------------------------------------------------------*/
/* Process the user configuration value */
/*--------------------------------------------------------------------*/
if (usrrc != nil(char))
{
if ((fp = FOPEN(usrrc, "r", TEXT)) == nil(FILE)) {
printmsg(0, "Cannot open user configuration file \"%s\"", usrrc);
return FALSE;
}
success = getconfig(fp, USER_CONFIG, program, table, configFlags);
fclose(fp);
if (!success)
return FALSE;
}
/*--------------------------------------------------------------------*/
/* Validate that all required parameters were given */
/*--------------------------------------------------------------------*/
for (tptr = table; tptr->sym != nil(char); tptr++) {
if ((tptr->bits & (B_REQUIRED | B_FOUND)) == B_REQUIRED)
{
printmsg(0, "%s configuration parameter \"%s\" must be set.",
(tptr->bits & B_GLOBAL) ? "System" : "User",
tptr->sym);
success = FALSE;
} /* if */
} /* for */
return success;
} /*configure*/
/*--------------------------------------------------------------------*/
/* g e t r c n a m e s */
/* */
/* Return the name of the configuration files */
/*--------------------------------------------------------------------*/
#define SYSRCSYM "UUPCSYSRC"
#define USRRCSYM "UUPCUSRRC"
#define SYSDEBUG "UUPCDEBUG" /* Initialize debug level for UUPC ahd */
static boolean getrcnames(char **sysp,char **usrp)
{
char *debugp = NULL; /* Pointer to debug environment variable */
if ((*sysp = getenv(SYSRCSYM)) == nil(char))
{
printf("environment variable %s must be specified\n", SYSRCSYM);
return FALSE;
}
*usrp = getenv(USRRCSYM);
debugp = getenv(SYSDEBUG);
if ( debugp != nil(char)) /* Debug specified in environment? */
debuglevel = atoi(debugp); /* Yes --> preset debuglevel for user */
return TRUE;
} /*getrcnames*/